package main

import (
	"aqielife.cn/spider/db"
	"aqielife.cn/spider/utils"
	"log"
	"net/http"
	"regexp"
	"strconv"
	"strings"

	"github.com/PuerkitoBio/goquery"
)

var (
	BaseUrl = "https://movie.douban.com/top250"
)

type DoubanMovie struct {
	Title    string
	Subtitle string
	Other    string
	Desc     string
	Year     int
	Area     string
	Tag      string
	Star     string
	Comment  string
	Quote    string
}

type Page struct {
	Page int
	Url  string
}

// 分析电影数据
func ParseMovies(doc *goquery.Document) (movies []DoubanMovie) {
	doc.Find("#content > div > div.article > ol > li").Each(func(i int, s *goquery.Selection) {
		title := s.Find(".hd a span").Eq(0).Text()

		subtitle := s.Find(".hd a span").Eq(1).Text()
		subtitle = strings.TrimLeft(subtitle, "  / ")

		other := s.Find(".hd a span").Eq(2).Text()
		other = strings.TrimLeft(other, "  / ")

		desc := strings.TrimSpace(s.Find(".bd p").Eq(0).Text())
		DescInfo := strings.Split(desc, "\n")
		desc = DescInfo[0]

		movieDesc := strings.Split(DescInfo[1], "/")
		year := utils.GetNumByStr(strings.TrimSpace(movieDesc[0]))
		area := strings.TrimSpace(movieDesc[1])
		tag := strings.TrimSpace(movieDesc[2])

		star := s.Find(".bd .star .rating_num").Text()

		comment := strings.TrimSpace(s.Find(".bd .star span").Eq(3).Text())
		compile := regexp.MustCompile("[0-9]")
		comment = strings.Join(compile.FindAllString(comment, -1), "")

		quote := s.Find(".quote .inq").Text()

		movie := DoubanMovie{
			Title:    title,
			Subtitle: subtitle,
			Other:    other,
			Desc:     desc,
			Year:     year,
			Area:     area,
			Tag:      tag,
			Star:     star,
			Comment:  comment,
			Quote:    quote,
		}

		log.Printf("i: %d, movie: %v", i, movie)
		movies = append(movies, movie)
	})

	return movies
}

// 获取分页
func GetPages(url string) []Page {
	err, doc := doRequest(url)
	if err != nil {
		log.Fatal(err)
	}
	var pages []Page
	pages = append(pages, Page{Page: 1, Url: ""})
	find := doc.Find("#content > div > div.article > div.paginator > a")
	find.Each(func(i int, s *goquery.Selection) {
		page, _ := strconv.Atoi(s.Text())
		url, _ := s.Attr("href")

		pages = append(pages, Page{
			Page: page,
			Url:  url,
		})
	})

	return pages
}

/**
 * 替代 goquery.NewDocument
 */
func doRequest(url string) (error, *goquery.Document) {
	client := &http.Client{}
	request, err := http.NewRequest("GET", url, nil)
	if err != nil {
		log.Fatal(err)
	}
	request.Header.Add("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36")
	response, _ := client.Do(request)
	defer response.Body.Close()
	if response.StatusCode != 200 {
		log.Fatal("请求失败")
	}
	doc, err := goquery.NewDocumentFromReader(response.Body)
	return err, doc
}

// 新增数据
func Add(movies []DoubanMovie) {
	if err := db.DB.Create(&movies).Error; err != nil {
		log.Printf("db.Create err : %v", err)
	} else {
		log.Println("批量新增成功: ", len(movies))
	}
}

func Start() {
	var movies []DoubanMovie

	pages := GetPages(BaseUrl)
	for _, page := range pages {
		err, doc := doRequest(strings.Join([]string{BaseUrl, page.Url}, ""))
		if err != nil {
			log.Println(err)
		}

		movies = append(movies, ParseMovies(doc)...)
	}

	Add(movies)
}

func main() {
	Start()
	//延时关闭数据库连接
	sqlDB, _ := db.DB.DB()
	defer sqlDB.Close()
}
